package com.mornd.gulimall.auth.web.v1;

import com.mornd.gulimall.apis.member.IMemberClient;
import com.mornd.gulimall.apis.member.to.MemberLoginTo;
import com.mornd.gulimall.common.core.constant.LoginConstant;
import com.mornd.gulimall.common.core.constant.ServerUrls;
import com.mornd.gulimall.common.core.entity.SessionUser;
import com.mornd.gulimall.common.core.result.R;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

import javax.annotation.Resource;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpSession;
import java.util.List;

/**
 * @author: mornd
 * @dateTime: 2023/8/18 - 22:21
 */

@Slf4j
@Controller
public class LoginController {
    @Resource
    private IMemberClient memberClient;

    /**
     * 账号登录
     * <p>
     * spring session 通过filter替换掉tomcat的session，将session数据存入redis，通过cookie中jsessionid读取数据
     *
     * @param to                 表单数据
     * @param bindingResult
     * @param redirectAttributes
     * @param session            此时的session已被替换为 org.springframework.session.web.http.SessionRepositoryFilter.SessionRepositoryRequestWrapper.HttpSessionWrapper.org.springframework.session.data.redis.RedisIndexedSessionRepository.RedisSession
     * @return
     */
    @PostMapping("/login/account")
    public String login(@Validated MemberLoginTo to,
                        BindingResult bindingResult,
                        RedirectAttributes redirectAttributes,
                        HttpSession session) {
        String redirect = "redirect:" + ServerUrls.AUTH + "/login.html";

        if (bindingResult.hasErrors()) {
            // 表单校验不通过
            List<FieldError> fieldErrors = bindingResult.getFieldErrors();
            String defaultMessage = fieldErrors.get(0).getDefaultMessage();
            redirectAttributes.addFlashAttribute("error", "注册失败，" + defaultMessage);
            return redirect;
        }

        R<SessionUser> r = null;
        try {
            r = memberClient.login(to);
        } catch (Exception e) {
            // 服务调用异常，不可控异常，需要记录日志
            log.error(e.getMessage());
            // 服务超时 feign.RetryableException: Read timed out executing POST http://service-member/member/member/login
            // 服务不可用 feign.FeignException$ServiceUnavailable: [503] during [POST] to [http://service-member/member/member/login] [IMemberClient#login(MemberLoginTo)]: [Load balancer does not contain an instance for the service service-member]
            redirectAttributes.addFlashAttribute("error", "登录失败，服务器异常");
            return redirect;
        }

        if (r.isFail()) {
            // 可控异常
            redirectAttributes.addFlashAttribute("error", r.getMsg());
            return redirect;
        }

        SessionUser sessionUser = r.getData();

        session.setAttribute(LoginConstant.SESSION_USER, sessionUser);

        return "redirect:" + ServerUrls.PRODUCT;
    }
}
